﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OAuth;
using System.Net;
using Butterfly.Properties;
using System.IO;
using System.Diagnostics;
using Butterfly.OAuth;

namespace Butterfly.SNS
{
    // Should be singleton
    public class SinaApi
    {
        private OAuthBase oAuth;
        private OAuthBase OAuth
        {
            get
            {
                if (oAuth == null)
                {
                    oAuth = BuildOAuthObject();
                    return oAuth;
                }
                else
                {
                    return oAuth;
                }
            }
        }

        private ApiAdresses apiAdresses;

        public SinaApi()
        {
            this.apiAdresses = new ApiAdresses();
            this.apiAdresses.AccessTokenUrl = new Uri(Settings.Default.Sina_AccessTokenUrl);
            this.apiAdresses.AuthorizationUrl = new Uri(Settings.Default.Sina_AuthorizationUrl);
            this.apiAdresses.RequestTokenUrl = new Uri(Settings.Default.Sina_RequestTokenUrl);
            this.apiAdresses.StatusUrl = new Uri(Settings.Default.Sina_StatusUrl);
        }

        public bool RequestOAuth()
        {
            OAuth.OnAuthorizationChanged += this.OnAuthorizationChanged;
            OAuth.StartAuth();

            return true;
        }

        public void GetAccess(string verifier)
        {
            OAuth.GetAccessToken(verifier);
        }

        private void OnAuthorizationChanged(object sender, AuthEventArgs e)
        {
            if (e.IsAuthorized)
            {
                Settings.Default.Sina_AccessToken = OAuth.accessToken;
                Settings.Default.Sina_AccessTokenSecret = OAuth.accessTokenSecret;
                Settings.Default.Save();
            }
        }

        private OAuthBase BuildOAuthObject()
        {
            OAuthBase oAuth = null; ;

            string accessToken = Settings.Default.Sina_AccessToken;
            string accessTokenSecret = Settings.Default.Sina_AccessTokenSecret;

            if (String.IsNullOrEmpty(accessToken) || String.IsNullOrEmpty(accessTokenSecret))
            {
                oAuth = new SinaOAuth(this.apiAdresses);
            }
            else
            {
                oAuth = new SinaOAuth(this.apiAdresses, accessToken, accessTokenSecret);
            }

            return oAuth;

        }

        public bool PostMessage(string content)
        {
            Uri uri = this.apiAdresses.StatusUrl;
            string oAuthHeader = this.OAuth.BuildAuthHeader(RequestCategory.Status, RequestType.Post);

            // build request
            StringBuilder requestBody = new StringBuilder("<?xml version='1.0' encoding='UTF-8'?>");
            requestBody.Append("<entry xmlns:ns0=\"http://www.w3.org/2005/Atom\" xmlns:db=\"http://www.douban.com/xmlns/\">");
            requestBody.AppendFormat("<content>{0}</content>", content);
            requestBody.Append("</entry>");
            Encoding encoding = Encoding.GetEncoding("utf-8");
            byte[] data = encoding.GetBytes(requestBody.ToString());

            // Http Request
            HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
            request.Headers.Set("Authorization", oAuthHeader);
            request.ContentType = "application/atom+xml";
            request.Method = "POST";
            request.ContentLength = data.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                StreamReader stream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
                string responseBody = stream.ReadToEnd();
                stream.Close();
                response.Close();

                Trace.TraceInformation("Post status succeed!");
            }
            catch (WebException e)
            {
                StreamReader stream = new StreamReader(e.Response.GetResponseStream(), System.Text.Encoding.UTF8);
                string responseBody = stream.ReadToEnd();
                stream.Close();

                Trace.TraceError("Post status failed! Reason: {0}", responseBody);
            }

            return true;
        }

    }
}
